package cn.lzwei.bilimall.ware.service.impl;

import cn.lzwei.bilimall.ware.entity.PurchaseDetailEntity;
import cn.lzwei.bilimall.ware.feign.ProductFeignService;
import cn.lzwei.bilimall.ware.service.PurchaseDetailService;
import cn.lzwei.bilimall.ware.service.WareSkuService;
import cn.lzwei.bilimall.ware.vo.MergePurchaseVo;
import cn.lzwei.bilimall.ware.vo.PurchaseDetailsDoneVo;
import cn.lzwei.bilimall.ware.vo.PurchaseDoneVo;
import cn.lzwei.common.constant.WareConstant;
import cn.lzwei.common.utils.R;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.lzwei.common.utils.PageUtils;
import cn.lzwei.common.utils.Query;

import cn.lzwei.bilimall.ware.dao.PurchaseDao;
import cn.lzwei.bilimall.ware.entity.PurchaseEntity;
import cn.lzwei.bilimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Resource
    PurchaseDetailService purchaseDetailService;
    @Resource
    WareSkuService wareSkuService;
    @Resource
    ProductFeignService productFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 模拟完成采购：更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存
     */
    @Transactional
    @Override
    public void done(PurchaseDoneVo purchaseDoneVo) {
        //此采购单状态为新建、已分配、已领取时才可被完成
        Long PurchaseId = purchaseDoneVo.getId();
        PurchaseEntity purchase = this.getById(PurchaseId);
        Integer purchaseCanDone = purchase.getStatus();
        if(purchaseCanDone==WareConstant.PurchaseType.CREATE.getCode() ||
                purchaseCanDone==WareConstant.PurchaseType.ASSIGNED.getCode() ||
                purchaseCanDone==WareConstant.PurchaseType.RECEIVED.getCode()){
            //标志位：用于判断采购单状态
            boolean purchaseStatus=true;
            //遍历采购需求列表
            List<PurchaseDetailsDoneVo> items = purchaseDoneVo.getItems();
            for (PurchaseDetailsDoneVo item : items) {
                //采购需求状态为新建、已分配、正在采购时才可被完成
                Long itemId = item.getItemId();
                PurchaseDetailEntity purchaseDetailEntity = purchaseDetailService.getById(itemId);
                Integer purchaseDetailCanDone = purchaseDetailEntity.getStatus();
                if(purchaseDetailCanDone==WareConstant.PurchaseDetailType.CREATE.getCode() ||
                        purchaseDetailCanDone==WareConstant.PurchaseDetailType.ASSIGNED.getCode() ||
                        purchaseDetailCanDone==WareConstant.PurchaseDetailType.BUYING.getCode()){
                    //1.更新采购需求状态
                    Integer status = item.getStatus();
                    purchaseDetailEntity.setStatus(status);
                    purchaseDetailService.updateById(purchaseDetailEntity);
                    if(status==4){
                        //采购失败
                        purchaseStatus=false;
                    }else{
                        //采购完成
                        //2.添加或者修改采购完成的商品库存：需要skuid、仓库id、库存、sku名字（调用远程服务）
                        Long skuId = purchaseDetailEntity.getSkuId();
                        Long wareId = purchaseDetailEntity.getWareId();
                        Integer skuNum = purchaseDetailEntity.getSkuNum();
                        Map<String,Object> skuInfo = (Map<String, Object>) productFeignService.info(skuId).get("skuInfo");
                        String skuName= (String) skuInfo.get("skuName");
                        wareSkuService.addWare(skuId,wareId,skuNum,skuName);
                    }
                }
            }
            //3.根据采购需求列表的状态更新采购单状态
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setId(PurchaseId);
            purchaseEntity.setStatus(purchaseStatus?WareConstant.PurchaseType.FINISHED.getCode():WareConstant.PurchaseType.HASEXECPTION.getCode());
            purchaseEntity.setUpdateTime(new Date());
            this.updateById(purchaseEntity);
        }
    }
    /**
     * 模拟领取采购单：需要验证采购单、采购需求的状态
     */
    @Transactional
    @Override
    public void receivedPurchase(List<Long> ids) {
        //1.验证采购单状态：只有新建、已分配的采购单可以被领取
        List<PurchaseEntity> purchaseEntities = ids.stream().map(item -> {
            PurchaseEntity purchaseEntity = this.getById(item);
            return purchaseEntity;
        }).filter(item->{
            Integer status = item.getStatus();
            if(status==WareConstant.PurchaseType.CREATE.getCode() || status==WareConstant.PurchaseType.ASSIGNED.getCode()){
                return true;
            }
            return false;
        }).map(item->{
            //2.更新采购单状态、更新时间
            item.setStatus(WareConstant.PurchaseType.RECEIVED.getCode());
            item.setUpdateTime(new Date());
            return item;
        }).collect(Collectors.toList());
        this.updateBatchById(purchaseEntities);
        //遍历每一份采购单
        for (PurchaseEntity purchaseEntity : purchaseEntities) {
            //3.获取采购单下的采购需求：状态必须为新建、已分配
            Long id = purchaseEntity.getId();
            List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.listDetailByPurchaseId(id);
            List<PurchaseDetailEntity> collect = purchaseDetailEntities.stream().map(item -> {
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                purchaseDetailEntity.setId(item.getId());
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailType.BUYING.getCode());
                return purchaseDetailEntity;
            }).collect(Collectors.toList());
            //4.更新采购需求的状态
            purchaseDetailService.updateBatchById(collect);
        }
    }

    /**
     * 合并采购需求：1.指定采购单，更新对应的采购需求以及采购单信息；2.无指定采购单，创建采购单并更新采购需求以及采购单信息
     */
    @Transactional
    @Override
    public void mergePurchase(MergePurchaseVo mergePurchaseVo) {
        //判断是否有指定采购单
        Long purchaseId = mergePurchaseVo.getPurchaseId();
        if(purchaseId==null){
            //新建采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setStatus(WareConstant.PurchaseType.CREATE.getCode()); //新建状态
            this.save(purchaseEntity);
            purchaseId=purchaseEntity.getId();
        }
        //TODO 确认采购单状态是0、1才可以合并
        //1.获取采购单集合
        List<Long> items = mergePurchaseVo.getItems();
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = items.stream().map(item -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setId(item);
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailType.ASSIGNED.getCode());
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        //2.更新采购需求上的采购单id和状态
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
        //3.修改采购单的更新时间
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(finalPurchaseId);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

    /**
     * 获取采购单列表：状态为 新建、已分配
     */
    @Override
    public PageUtils getUnrecivePurchase(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",0).or().eq("status",1);
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

}